﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Reflection;

namespace ViewMaker.Core.Controls
{
    public static class ViewControlTypeExtenion
    {
        public static ViewElement Create(this ViewControlType controlType)
        {
            switch (controlType)
            {
                case ViewControlType.None: return new NoneViewControl();
                case ViewControlType.Label: return new LabelViewControl();
                case ViewControlType.TextBox: return new TextBoxViewControl();
                case ViewControlType.ComboBox: return new ComboBoxViewControl();
                case ViewControlType.ListBox: return new ListBoxViewControl();
                case ViewControlType.RadioButtonList: return new RadioButtonListViewControl();
                case ViewControlType.ItemsControl: return new ItemsControlViewControl();
                case ViewControlType.CheckBox: return new CheckBoxViewControl();
                case ViewControlType.DatePicker: return new DatePickerViewControl();
                case ViewControlType.Button: return new ButtonViewControl();
                case ViewControlType.Hyperlink: return new HyperlinkViewControl();
                case ViewControlType.Canvas: return new CanvasViewControl();
                case ViewControlType.StackPanel: return new StackPanelViewControl();
                case ViewControlType.Grid: return new GridViewControl();
                case ViewControlType.DataGrid: return new DataGridViewControl();
                case ViewControlType.DataGridTextColumn: return new DataGridTextColumnViewElement();
                case ViewControlType.DataGridCheckBoxColumn: return new DataGridCheckBoxColumnViewElement();
                case ViewControlType.DataGridComboBoxColumn: return new DataGridComboBoxColumnViewElement();
                case ViewControlType.TreeView: return new TreeViewControl();
                case ViewControlType.TabControl: return new TabControlViewControl();
                case ViewControlType.Literal: return new LiteralViewControl();
                case ViewControlType.UserControl: return new UserControlViewControl();
            }
            return new NoneViewControl();
        }

        public static List<Tuple<string, Type>> GetAdditinalProperties(this ViewControlType controlType)
        {
            switch (controlType)
            {
                case ViewControlType.None: return GetAdditinalProperties(typeof(NoneViewControl), typeof(UIElement));
                case ViewControlType.Label: return GetAdditinalProperties(typeof( LabelViewControl), typeof(Label));
                case ViewControlType.TextBox: return GetAdditinalProperties(typeof( TextBoxViewControl), typeof(TextBox));
                case ViewControlType.ComboBox: return GetAdditinalProperties(typeof( ComboBoxViewControl), typeof(ComboBox));
                case ViewControlType.ListBox: return GetAdditinalProperties(typeof( ListBoxViewControl), typeof(ListBox));
                case ViewControlType.RadioButtonList: return GetAdditinalProperties(typeof( RadioButtonListViewControl), typeof(RadioButton));
                case ViewControlType.ItemsControl: return GetAdditinalProperties(typeof( ItemsControlViewControl), typeof(ItemsControl));
                case ViewControlType.CheckBox: return GetAdditinalProperties(typeof( CheckBoxViewControl), typeof(CheckBox));
                case ViewControlType.DatePicker: return GetAdditinalProperties(typeof( DatePickerViewControl), typeof(DatePicker));
                case ViewControlType.Button: return GetAdditinalProperties(typeof( ButtonViewControl), typeof(Button));
#if !SILVERLIGHT
                case ViewControlType.Hyperlink: return GetAdditinalProperties(typeof(HyperlinkViewControl), typeof(Label));
#else
                case ViewControlType.Hyperlink: return GetAdditinalProperties(typeof(HyperlinkViewControl), typeof(HyperlinkButton));
#endif
                case ViewControlType.Canvas: return GetAdditinalProperties(typeof(CanvasViewControl), typeof(Canvas));
                case ViewControlType.StackPanel: return GetAdditinalProperties(typeof( StackPanelViewControl), typeof(StackPanel));
                case ViewControlType.Grid: return GetAdditinalProperties(typeof( GridViewControl), typeof(Grid));
                case ViewControlType.DataGrid: return GetAdditinalProperties(typeof(DataGridViewControl), typeof(DataGrid));
                case ViewControlType.DataGridTextColumn: return GetAdditinalProperties(typeof(DataGridTextColumnViewElement), typeof(DataGridTextColumn));
                case ViewControlType.DataGridCheckBoxColumn: return GetAdditinalProperties(typeof(DataGridCheckBoxColumnViewElement), typeof(DataGridCheckBoxColumn));
#if !SILVERLIGHT
                case ViewControlType.DataGridComboBoxColumn: return GetAdditinalProperties(typeof(DataGridComboBoxColumnViewElement), typeof(DataGridComboBoxColumn));
#else
                case ViewControlType.DataGridComboBoxColumn: return GetAdditinalProperties(typeof(DataGridComboBoxColumnViewElement), typeof(DataGridTemplateColumn));
#endif
                case ViewControlType.TreeView: return GetAdditinalProperties(typeof(TreeViewControl), typeof(TreeView));
                case ViewControlType.TabControl: return GetAdditinalProperties(typeof(TabControlViewControl), typeof(TabControl));
                case ViewControlType.Literal: return GetAdditinalProperties(typeof(LiteralViewControl), typeof(UIElement));
                case ViewControlType.UserControl: return GetAdditinalProperties(typeof(UserControlViewControl), typeof(UserControl));
            }
            return new List<Tuple<string, Type>>();
        }

        static string[] exceptAdditinalProperties = new string[] { "Name" };

        private static List<Tuple<string, Type>> GetAdditinalProperties(Type viewControlType, Type controlType)
        {
            var list = new List<Tuple<string, Type>>();
            if (typeof(DependencyObject).IsAssignableFrom(controlType))
            {
                var dependencyProperties = controlType.GetFields(BindingFlags.Static | BindingFlags.Public|BindingFlags.FlattenHierarchy)
                    .Where(x => typeof(DependencyProperty).IsAssignableFrom(x.FieldType))
                    .OrderBy(x=>x.Name);
                foreach (var prop in dependencyProperties)
                {
                    string name = prop.Name.EndsWith("Property") ? prop.Name.Substring(0, prop.Name.Length - "Property".Length) : prop.Name;
                    if (!exceptAdditinalProperties.Any(x => x == name)  && !viewControlType.GetProperties().Any(x=>x.Name == name))
                    {
                        var dependency = (DependencyProperty)prop.GetValue(null);
#if !SILVERLIGHT
                        list.Add(new Tuple<string, Type>(name, dependency.PropertyType));
#else
                        var defValue = dependency.GetMetadata(controlType).DefaultValue;
                        if (defValue != null)
                        {
                            list.Add(new Tuple<string, Type>(name, defValue.GetType()));
                        }
#endif
                    }
                }
            }
            return list;
        }

    }
}
